package classfile

type MemberInfo struct {
	constantPool    ConstantPool
	accessFlags     uint16
	nameIndex       uint16
	descriptorIndex uint16
	attributes      []AttributeInfo
}

func (self MemberInfo) ConstantValueAttr() *ConstantValueAttr {
	if self.attributes != nil {
		for _, attr := range self.attributes {
			if r, ok := (attr).(*ConstantValueAttr); ok {
				return r
			}
		}
	}
	return nil
}

func (self MemberInfo) GetClassName() string {
	return self.constantPool.getClassName(self.nameIndex)
}

func (self MemberInfo) GetNameAndDescriptor() (name string, desc string) {
	nameAndType := self.constantPool.GetConstant(self.descriptorIndex).(*Constant_Name_And_Type)
	name = nameAndType.name.Value
	desc = nameAndType.describe.Value
	return
}

func (self MemberInfo) AccessFlags() uint16 {
	return self.accessFlags
}

func (self MemberInfo) Name() string {
	c := self.constantPool.GetConstant(self.nameIndex).(*Constant_Utf8).Value
	return c
}

func (self MemberInfo) Descriptor() string {
	c := self.constantPool.GetConstant(self.descriptorIndex).(*Constant_Utf8).Value
	return c
}

func (self MemberInfo) CodeAttribute() *CodeAttr {
	if self.attributes != nil {
		for _, attr := range self.attributes {
			if r, ok := (attr).(*CodeAttr); ok {
				return r
			}
		}
	}
	return nil
}

func ReadMemberInfo(cr *ClassReader, cp ConstantPool) *MemberInfo {

	mem := &MemberInfo{
		constantPool:    cp,
		accessFlags:     cr.ReadUInt16(),
		nameIndex:       cr.ReadUInt16(),
		descriptorIndex: cr.ReadUInt16(),
		attributes:      readAttrs(cr, cp),
	}
	return mem
}

func readAttrs(cr *ClassReader, cp ConstantPool) []AttributeInfo {
	attributesCount := cr.ReadUInt16()
	attributes := make([]AttributeInfo, attributesCount)
	if attributesCount > 0 {
		for i := range attributes {
			attributes[i] = NewAttributeInfo(cr, cp)
		}
	}
	return attributes
}
